#include "mainwindow.h"
#include "labelscene.h"
#include "labelview.h"
#include "labelinputdialog.h"
#include <QAction>
#include <QMenuBar>
#include <QToolBar>
#include <QRectF>
#include <QLayout>
#include <QWidget>
#include <QApplication>
#include <QScreen>
#include <QToolButton>
#include <QButtonGroup>
#include <QIcon>
#include <QCheckBox>
#include <QMessageBox>
#include <QInputDialog>
#include <QListView>
#include <QStandardPaths>
#include <QFileDialog>
#include <QLabel>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    createActions();
    createMenus();
    createToolBars();

    //创建scene和view，布局
    scene = new LabelScene(this);
    QHBoxLayout *layout = new QHBoxLayout;
    view = new LabelView(scene);
    view->setRenderHint(QPainter::Antialiasing, true);
    view->setMouseTracking(true);
    layout->addWidget(view, 4);
    /**
     *     model = new SceneItemModel(this);
    QListView *listView = new QListView(this);
    listView->setModel(model);
    listView->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);

    labelNameListModel = new LabelNameListModel(this);
    model->setLabelNameList(labelNameListModel);
    QListView *labelNameListView = new QListView(this);
    labelNameListView->setModel(labelNameListModel);
    labelNameListView->setEditTriggers(QListView::NoEditTriggers);    // 禁止编辑

    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(listView);
    rightLayout->addWidget(labelNameListView);
    QWidget *list = new QWidget(this);
    list->setLayout(rightLayout);
     */
    model = new LabelListModel(this);
    QListView *labelListView = new QListView(this);
    labelListView->setModel(model);
    labelListView->setEditTriggers(QAbstractItemView::NoEditTriggers);

    labelNameListModel = new LabelNameListModel(this);
    model->setLabelNameList(labelNameListModel);
    QListView *labelNameListView = new QListView(this);
    labelNameListView->setModel(labelNameListModel);
    labelNameListView->setEditTriggers(QListView::NoEditTriggers);

    imageListModel = new QStringListModel(this);
    imageListView = new QListView(this);
    imageListView->setModel(imageListModel);
    connect(imageListView, &QListView::clicked, this, [this](const QModelIndex &index){
        // Retrieve the selected image path from the image list model.
        // 从 imageListModel 中获取所选图片的路径。
        QString imagePath = imageListModel->data(index, Qt::DisplayRole).toString();

        // Clear the current scene.
        // 清空当前 scene。
        scene->clear();
        scene->cursorFollower = nullptr;
        qDebug() << "is nullptr" << (scene->cursorFollower == nullptr);
        // Load the selected image.
        // 加载所选图片。
        pix = QPixmap(imagePath);
        this->imagePath = imagePath;
        if (pix.isNull()) {
            QMessageBox::warning(this, tr("Error"), tr("Failed to load image: %1").arg(imagePath));
            return;
        }

        scene->addPixmap(pix);
        scene->setSceneRect(pix.rect());

        // Clear the labelNameListModel data.
        // 清空 labellistmodel 中的数据。
        if (model) {
            model->clear();
        }
        if(scene->mode() == LabelScene::CreatePolygon)
        {

            createPolygonAct->triggered();
            qDebug() << "create";
        }else if(scene->mode() == LabelScene::CreateRectangle)
            {
            createRectangleAct->triggered();
        }else if(scene->mode() == LabelScene::EditPolygon)
            {
            editPolygonAct->triggered();
        }
    });
    // for classification
    QStringList flags = {"__ignore__", "cat", "dog"};
    flagModel = new QStringListModel(flags);

    // 列表视图
    flagView = new QListView;
    flagView->setModel(flagModel);
    flagView->setSelectionMode(QAbstractItemView::SingleSelection);  // 单选模式

    // 显示当前选中项的 Label
    auto *selectedLabel = new QLabel("当前选中：无");

    // 连接选中项变化
    QObject::connect(flagView->selectionModel(), &QItemSelectionModel::currentChanged,
                     [=](const QModelIndex &current, const QModelIndex &) {
                         if (current.isValid()) {
                             QString label = flagModel->data(current, Qt::DisplayRole).toString();
                             selectedLabel->setText("当前选中：" + label);
                         } else {
                             selectedLabel->setText("当前选中：无");
                         }
                     });

    // 初始选中第一个
    flagView->setCurrentIndex(model->index(0, 0));
    auto *flagLayout = new QVBoxLayout;
    flagLayout->addWidget(flagView);
    flagLayout->addWidget(selectedLabel);
    QWidget *flagListView = new QWidget;
    flagListView->setLayout(flagLayout);



    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(labelListView);
    rightLayout->addWidget(labelNameListView);
    rightLayout->addWidget(imageListView);
    rightLayout->addWidget(flagListView);
    QWidget *rightWidget = new QWidget(this);
    rightWidget->setLayout(rightLayout);

    connect(scene, &LabelScene::polygonCreated, this, &MainWindow::polygonCreated);



    layout->addWidget(rightWidget, 1);
    QWidget *widget = new QWidget;
    widget->setLayout(layout);
    setCentralWidget(widget);

    setWindowTitle(tr("标签"));
    setWindowState(Qt::WindowMaximized);
    // setWindowFlag(Qt::MSWindowsFixedSizeDialogHint);
    resize(800, 500);

    // QPixmap image = QPixmap(":/images/example.jpg");
    // QGraphicsPixmapItem* imageItem = new QGraphicsPixmapItem(image);
    // scene->addItem(imageItem);
    // scene->setSceneRect(0, 0, imageItem->boundingRect().width(), imageItem->boundingRect().height());


    view->scale(1, 1);

    createPolygonAct->triggered();
}

MainWindow::~MainWindow() {}
void MainWindow::createMenus()
{
    fileMenu = new QMenu(tr("&文件"), this);
    fileMenu->addAction(openAct);
    fileMenu->addAction(saveAsAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

    editMenu = new QMenu(tr("&编辑"), this);
    editMenu->addAction(createPolygonAct);
    editMenu->addAction(createRectangleAct);



    menuBar()->addMenu(fileMenu);
    menuBar()->addMenu(editMenu);
}

void MainWindow::createActions()
{


    openAct = new QAction(QIcon(":/icons/folder.png"), tr("&打开文件夹"), this);
    openAct->setShortcuts(QKeySequence::Open);

    connect(openAct, &QAction::triggered, this, &MainWindow::openFolder);

    openImageAct = new QAction(QIcon(":/icons/folder.png"), tr("&打开图片"), this);
    connect(openImageAct, &QAction::triggered, this, &MainWindow::openImage);

    openJsonAct = new QAction(QIcon(":/icons/folder.png"), tr("&打开Json文件"), this);
    connect(openJsonAct, &QAction::triggered, this, &MainWindow::openJson);


    saveAsAct = new QAction(QIcon(":/icons/save.png"), tr("&保存到"), this);
    connect(saveAsAct, &QAction::triggered, this, &MainWindow::saveAs);

    exitAct = new QAction(QIcon(":/icons/exit.png"), tr("&退出"), this);
    exitAct->setShortcuts(QKeySequence::Quit);
    connect(exitAct, &QAction::triggered, this, &MainWindow::close);


    createPolygonAct = new QAction(QIcon(":/icons/polygon.png"), tr("&创建多边形"), this);
    createPolygonAct->setCheckable(true);
    createPolygonAct->setData(LabelScene::CreatePolygon);
    connect(createPolygonAct, &QAction::triggered, this, &MainWindow::modeChange);


    createRectangleAct = new QAction(QIcon(":/icons/rectangle.png"), tr("&创建长方形"), this);
    createRectangleAct->setCheckable(true);
    createRectangleAct->setData(LabelScene::CreateRectangle);
    connect(createRectangleAct, &QAction::triggered, this, &MainWindow::modeChange);

    editPolygonAct = new QAction(QIcon(":/icons/edit.png"), tr("&编辑多边形"), this);
    editPolygonAct->setCheckable(true);
    editPolygonAct->setData(LabelScene::EditPolygon);
    connect(editPolygonAct, &QAction::triggered, this, &MainWindow::modeChange);







    // italicAction = new QAction(QIcon(":/images/italic.png"), tr("Italic"), this);
    // italicAction->setCheckable(true);
    // italicAction->setShortcut(tr("Ctrl+I"));
    // connect(italicAction, &QAction::triggered, this, &MainWindow::handleFontChange);



}
void MainWindow::createToolBars()
{
    fileToolBar = addToolBar(tr("文件"));
    fileToolBar->addAction(openAct);
    fileToolBar->addAction(openImageAct);
    fileToolBar->addAction(openJsonAct);
    fileToolBar->addAction(saveAsAct);
    fileToolBar->addAction(exitAct);
    fileToolBar->setIconSize(QSize(30, 30));
    fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

    editToolBar = addToolBar(tr("编辑"));

    editToolBar->addAction(createPolygonAct);
    editToolBar->addAction(createRectangleAct);
    editToolBar->addSeparator();
    editToolBar->addAction(editPolygonAct);
    editToolBar->setIconSize(QSize(40, 40));
    editToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

}
void MainWindow::modeChange()
{
    if(!isImageOpen) {
        createPolygonAct->setDisabled(true);
        createRectangleAct->setDisabled(true);
        editPolygonAct->setDisabled(true);
        return;
    }

    QAction *action = qobject_cast<QAction *>(sender());
    qDebug() << action;
    LabelScene::Mode mode = qvariant_cast<LabelScene::Mode>(action->data());

    scene->setMode(mode);

    createPolygonAct->setDisabled(false);
    createPolygonAct->setChecked(false);
    createRectangleAct->setDisabled(false);
    createRectangleAct->setChecked(false);
    editPolygonAct->setDisabled(false);
    editPolygonAct->setChecked(false);


    switch (mode) {
    case LabelScene::CreatePolygon:

        createPolygonAct->setDisabled(true);
        createPolygonAct->setChecked(true);
        break;
    case LabelScene::CreateRectangle:
        createRectangleAct->setDisabled(true);
        createRectangleAct->setChecked(true);
        break;
    case LabelScene::EditPolygon:
        editPolygonAct->setDisabled(true);
        editPolygonAct->setChecked(true);
        break;
    default:
        break;
    }


}

void MainWindow::polygonCreated(PolygonItem *polygonItem)
{
    showTextDialog(polygonItem, true);

    // 连接 item 的右键菜单信号（在 Edit 模式下使用）
    connect(polygonItem, &PolygonItem::requestDelete, this, &MainWindow::onItemRequestDelete);
    connect(polygonItem, &PolygonItem::requestModify, this, &MainWindow::onItemRequestModify);


}
void MainWindow::saveAs()
{
    QStringList options = {"多边形标注", "矩形标注", "分类任务"};

    bool ok;
    QString choice = QInputDialog::getItem(this, "选择任务类型", "请选择保存类型：", options, 0, false, &ok);

    if (ok && !choice.isEmpty()) {
        if (choice == "多边形标注") {
            // qDebug() << "width height" << pix.width() << pix.height();
            QFileInfo fileInfo(imagePath);

            // 获取同目录、同文件名，改扩展名为 .json
            QString savePath = fileInfo.path() + "/" + fileInfo.completeBaseName() + ".json";
            exportJsonPolygon(scene, imagePath, pix.width(), pix.height(), savePath);
        } else if (choice == "矩形标注") {
            QFileInfo fileInfo(imagePath);

            // 获取同目录、同文件名，改扩展名为 .json
            QString savePath = fileInfo.path() + "/" + fileInfo.completeBaseName() + ".json";
            exportJsonRectangle(scene, imagePath, pix.width(), pix.height(), savePath);
        } else if (choice == "分类任务") {
            QFileInfo fileInfo(imagePath);

            // 获取同目录、同文件名，改扩展名为 .json
            QString savePath = fileInfo.path() + "/" + fileInfo.completeBaseName() + ".json";
            exportJsonClassification(scene, imagePath, pix.width(), pix.height(), savePath);
        }
    } else {
        qDebug() << "用户取消了保存类型选择";
    }
}

void MainWindow::zoomIn()
{

}

void MainWindow::zoomOut()
{

}

void MainWindow::normalSize()
{

}

void MainWindow::openFolder()
{

    QString defaultDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);

    // Open a folder selection dialog with the default directory.
    // 打开选择文件夹对话框，默认目录为 Pictures 目录。
    QString dir = QFileDialog::getExistingDirectory(this, tr("选择文件夹"), defaultDir);

    if (dir.isEmpty())
        return;
    isImageOpen = true;

    // Clear previous image list and scene.
    // 清空之前的图片列表和 scene 内容。

    qDebug() << imageListModel;
    if (imageListModel) {
        imageListModel->setStringList(QStringList());
    }

    // qDebug() << scene;
    scene->clear();
    scene->cursorFollower = nullptr;

    // // Also clear the labelNameListModel data.
    // // 同时清空 labellistmodel 中的数据。
    if (model) {
        model->clear(); // Ensure your model class provides a clear() method.
    }

    QDir directory(dir);
    // Define filters for common image file types.
    // 定义常见图片文件类型的过滤器。
    QStringList nameFilters;
    nameFilters << "*.png" << "*.jpg" << "*.jpeg" << "*.bmp" << "*.gif";

    // Retrieve image file names matching the filters.
    // 获取符合过滤条件的图片文件名列表。
    QStringList imageFiles = directory.entryList(nameFilters, QDir::Files);

    // Construct the full paths for each image.
    // 构造每个图片的完整路径。
    QStringList fullPaths;
    for (const QString &fileName : imageFiles) {
        fullPaths << directory.absoluteFilePath(fileName);
    }

    // Update the image list model with the full image paths.
    // 将完整图片路径列表更新到 imageListModel 中。
    if (imageListModel) {
        imageListModel->setStringList(fullPaths);
    }

    // Load the first image into the scene if available.
    // 如果存在图片，则加载第一张图片到 scene 中。
    if (!fullPaths.isEmpty()) {
        pix = QPixmap(fullPaths.first());
        imagePath = fullPaths.first();
        if (pix.isNull()) {
            QMessageBox::warning(this, tr("Error"), tr("Failed to load image: %1").arg(fullPaths.first()));
            return;
        }
        // Clear scene and add the pixmap.
        // 清空 scene 并添加 pixmap 项。
        scene->clear();
        scene->cursorFollower = nullptr;
        scene->addPixmap(pix);
        // Optionally, adjust the scene rect to match the image.
        // 可选：调整 scene 的范围以匹配图片尺寸。
        scene->setSceneRect(pix.rect());


        // scene->addItem(new VertexItem(QPointF(0, 0)));
        // scene->addItem(new VertexItem(QPointF(imageItem->boundingRect().width(), 0)));
        // scene->addItem(new VertexItem(QPointF(imageItem->boundingRect().width(), imageItem->boundingRect().height())));
    }
    // qDebug() << "Before isImageOpen";

    // qDebug() << "After isImageOpen";
    // qDebug() << createPolygonAct;
    createPolygonAct->triggered();
    // qDebug() << "after text";

}

void MainWindow::resizeEvent(QResizeEvent* event) {
    QMainWindow::resizeEvent(event);

    printSizes();
}

void MainWindow::printSizes() {
    qDebug() << width() << height();
    // qDebug() << "Window size:" << size();
    // qDebug() << "Window geometry:" << geometry();
    // qDebug() << "CentralWidget size:" << centralWidget()->size();
    qDebug() << "View size:" << view->size();
    qDebug() << "Viewport size:" << view->viewport()->size();
    // qDebug() << "Device Pixel Ratio:" << devicePixelRatio();
}

void MainWindow::showTextDialog(PolygonItem *item, bool isNew)
{
    QStringList list = labelNameListModel->labelNames();
    QString text = "";
    if(!list.isEmpty())
    {
        text = list[0];
    }

    LabelInputDialog dialog(list, isNew ? text  : item->text(), this);
    if (dialog.exec() == QDialog::Accepted) {
        QString text = dialog.text();
        // 继续使用 text 设置 item 的标签

        if (text != "") {
            if (!isNew  && labelNameListModel)
            {
                labelNameListModel->tryRename(item->text(), text);
            }
            item->setText(text);
            int row = model->indexOf(item);
            if (row >= 0) {
                QModelIndex idx = model->index(row, 0);
                model->setData(idx, text, Qt::EditRole);
            }
            if(isNew)
            {
                model->addItem(item, text);
            }


            // qDebug() << "old" << m_items[idx].text << "new" << newText;

        }
    }



}

void MainWindow::onItemRequestDelete(PolygonItem *item)
{
    if (QMessageBox::question(this, "删除", "确定删除该项吗？") == QMessageBox::Yes) {
        scene->removeItem(item);
        for(VertexItem *item: item->vertexes())
        {
            scene->removeItem(item);
            item->deleteLater();
        }
        model->removeItem(item);
        item->deleteLater();
    }
}

void MainWindow::onItemRequestModify(PolygonItem *item)
{
    showTextDialog(item, false);
}

void MainWindow::exportJsonPolygon(QGraphicsScene* scene, const QString& imagePath, int imageWidth, int imageHeight, const QString& savePath)
{
    QJsonObject root;
    root["version"] = "4.0.0";
    root["flags"] = QJsonObject();  // 空对象

    QJsonArray shapes;

    for (QGraphicsItem* item : scene->items()) {
        // 尝试动态转换为 PolygonItem
        auto* polygon = dynamic_cast<PolygonItem*>(item);
        if (!polygon) continue;

        QJsonObject shapeObj;
        shapeObj["label"] = polygon->text();

        // 顶点列表
        QJsonArray pointsArray;
        for (VertexItem* vertex : polygon->vertexes()) {
            QPointF pos = vertex->pos();
            QJsonArray point;
            point.append(pos.x());
            point.append(pos.y());
            pointsArray.append(point);
        }
        shapeObj["points"] = pointsArray;

        shapeObj["group_id"] = QJsonValue(); // null
        shapeObj["shape_type"] = "polygon";
        shapeObj["flags"] = QJsonObject(); // 空对象

        shapes.append(shapeObj);
    }

    root["shapes"] = shapes;
    root["imagePath"] = imagePath;
    root["imageData"] = QJsonValue(); // null
    root["imageHeight"] = imageHeight;
    root["imageWidth"] = imageWidth;

    // 保存到文件
    QJsonDocument doc(root);
    QFile file(savePath);
    if (file.open(QIODevice::WriteOnly)) {
        file.write(doc.toJson(QJsonDocument::Indented));
        file.close();
        qDebug() << "JSON exported to:" << savePath;
    } else {
        qWarning() << "Failed to write JSON to file:" << savePath;
    }
}

void MainWindow::exportJsonRectangle(QGraphicsScene *scene, const QString &imagePath, int imageWidth, int imageHeight, const QString &savePath)
{
    QJsonObject root;
    root["version"] = "4.0.0";
    root["flags"] = QJsonObject();  // 空对象

    QJsonArray shapes;

    for (QGraphicsItem* item : scene->items()) {
        // 尝试动态转换为 PolygonItem
        auto* polygon = dynamic_cast<PolygonItem*>(item);
        if (!polygon) continue;

        QJsonObject shapeObj;
        shapeObj["label"] = polygon->text();

        // 顶点列表
        QJsonArray pointsArray;
        for (VertexItem* vertex : polygon->vertexes()) {
            QPointF pos = vertex->pos();
            QJsonArray point;
            point.append(pos.x());
            point.append(pos.y());
            pointsArray.append(point);
        }
        shapeObj["points"] = pointsArray;

        shapeObj["group_id"] = QJsonValue(); // null
        shapeObj["shape_type"] = "rectangle";
        shapeObj["flags"] = QJsonObject(); // 空对象

        shapes.append(shapeObj);
    }

    root["shapes"] = shapes;
    root["imagePath"] = imagePath;
    root["imageData"] = QJsonValue(); // null
    root["imageHeight"] = imageHeight;
    root["imageWidth"] = imageWidth;

    // 保存到文件
    QJsonDocument doc(root);
    QFile file(savePath);
    if (file.open(QIODevice::WriteOnly)) {
        file.write(doc.toJson(QJsonDocument::Indented));
        file.close();
        qDebug() << "JSON exported to:" << savePath;
    } else {
        qWarning() << "Failed to write JSON to file:" << savePath;
    }
}

void MainWindow::exportJsonClassification(QGraphicsScene *scene, const QString &imagePath, int imageWidth, int imageHeight, const QString &savePath)
{
    QJsonObject root;
    root["version"] = "4.0.0";

    QJsonObject flagsObj;
    QString currentFlag;
    QModelIndex currentIndex = flagView->currentIndex();  // 当前选中的索引
    if (currentIndex.isValid()) {
        currentFlag = flagModel->data(currentIndex, Qt::DisplayRole).toString();
    }

    for (const QString &flag : flagModel->stringList()) {
        flagsObj[flag] = (flag == currentFlag);
    }

    root["flags"] = flagsObj;


    root["shapes"] = QJsonArray();
    root["imagePath"] = imagePath;
    root["imageData"] = QJsonValue(); // null
    root["imageHeight"] = imageHeight;
    root["imageWidth"] = imageWidth;

    QJsonDocument doc(root);
    QFile file(savePath);
    if (file.open(QIODevice::WriteOnly)) {
        file.write(doc.toJson(QJsonDocument::Indented));
        file.close();
        qDebug() << "JSON exported to:" << savePath;
    } else {
        qWarning() << "Failed to write JSON to file:" << savePath;
    }
}

void MainWindow::openImage()
{
    QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
    QString filePath = QFileDialog::getOpenFileName(this,
                                                    tr("打开图片"), defaultPath, tr("Image Files (*.png *.jpg *.bmp *.jpeg)"));

    if (filePath.isEmpty()) {
        return;
    }

    isImageOpen = true;

    if (imageListModel) {
        imageListModel->setStringList(QStringList());
    }

    // qDebug() << scene;
    scene->clear();
    scene->cursorFollower = nullptr;

    // // Also clear the labelNameListModel data.
    // // 同时清空 labellistmodel 中的数据。
    if (model) {
        model->clear(); // Ensure your model class provides a clear() method.
    }

    // 加载选中的图片
        // Load the selected image
    QPixmap pix(filePath);
    if (pix.isNull()) {
        QMessageBox::warning(this, tr("Error"), tr("Failed to load image: %1").arg(filePath));
        return;
    }

    // 清空 scene 并重新添加图像
    // Clear the scene and add the new pixmap
    scene->clear();
    scene->cursorFollower = nullptr;

    imagePath = filePath;
    scene->addPixmap(pix);

    // 设置 scene 的范围匹配图片尺寸
    // Set the scene rect to match the image size
    scene->setSceneRect(pix.rect());

    // 更新 imageListModel，仅包含当前这一个图片
    // Update imageListModel to contain only the opened image
    if (imageListModel) {
        imageListModel->setStringList(QStringList() << filePath);
    }
    createPolygonAct->triggered();
}


void MainWindow::openJson()
{



    QString jsonPath = QFileDialog::getOpenFileName(
        this,
        tr("打开Json文件"),
        QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),  // 默认打开文档目录
        tr("JSON Files (*.json)")
        );

    if (jsonPath.isEmpty()) {
        return; // 用户取消
    }

    QFile file(jsonPath);
    if (!file.open(QIODevice::ReadOnly)) {
        QMessageBox::warning(this, tr("Error"), tr("Failed to open JSON file: %1").arg(jsonPath));
        return;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
    if (parseError.error != QJsonParseError::NoError) {
        QMessageBox::warning(this, tr("Parse Error"), tr("JSON parse error: %1").arg(parseError.errorString()));
        return;
    }

    QJsonObject root = doc.object();
    QString filePath = root.value("imagePath").toString();

    if (filePath.isEmpty()) {
        return;
    }

    isImageOpen = true;

    if (imageListModel) {
        imageListModel->setStringList(QStringList());
    }

    // qDebug() << scene;
    scene->clear();
    scene->cursorFollower = nullptr;

    // // Also clear the labelNameListModel data.
    // // 同时清空 labellistmodel 中的数据。
    if (model) {
        model->clear(); // Ensure your model class provides a clear() method.
    }

    // 加载选中的图片
    // Load the selected image
    QPixmap pix(filePath);
    if (pix.isNull()) {
        QMessageBox::warning(this, tr("Error"), tr("Failed to load image: %1").arg(filePath));
        return;
    }

    // 清空 scene 并重新添加图像
    // Clear the scene and add the new pixmap
    scene->clear();
    scene->cursorFollower = nullptr;

    imagePath = filePath;
    scene->addPixmap(pix);

    // 设置 scene 的范围匹配图片尺寸
    // Set the scene rect to match the image size
    scene->setSceneRect(pix.rect());

    // 更新 imageListModel，仅包含当前这一个图片
    // Update imageListModel to contain only the opened image
    if (imageListModel) {
        imageListModel->setStringList(QStringList() << filePath);
    }
    createPolygonAct->triggered();



    QJsonArray shapesArray = root.value("shapes").toArray();

    for (const QJsonValue &shapeVal : shapesArray) {
        QJsonObject shapeObj = shapeVal.toObject();
        QString label = shapeObj.value("label").toString();
        QString shapeType = shapeObj.value("shape_type").toString();
        if (shapeType == "rectangle")
        {
            QPolygonF polygon;
            PolygonItem* polygonItem = new PolygonItem(scene);
            QJsonArray pointsArray = shapeObj.value("points").toArray();
            int x1,y1,x2,y2;
            int i = 0;
            for (const QJsonValue &pointVal : pointsArray) {
                QJsonArray point = pointVal.toArray();
                if (point.size() != 2)
                    continue;
                if(i == 0)
                {
                    x1 = point[0].toDouble();
                    y1 = point[1].toDouble();
                }
                if(i == 1)
                {
                    x2 = point[0].toDouble();
                    y2 = point[1].toDouble();
                }
                i++;
            }
            polygon << QPointF(x1, y1);
            VertexItem* vertexItem = new VertexItem(QPointF(x1, y1), VertexItem::Placed, scene);
            vertexItem->setIndex(0);
            vertexItem->setPolygonItem(polygonItem);
            polygonItem->myVertexes.append(vertexItem);
            polygonItem->setText(label);
            scene->addItem(vertexItem);


            polygon << QPointF(x1, y2);
            polygon << QPointF(x2, y2);
            VertexItem* vertexItem2 = new VertexItem(QPointF(x2, y2), VertexItem::Placed, scene);
            vertexItem2->setIndex(1);
            vertexItem2->setPolygonItem(polygonItem);
            polygonItem->myVertexes.append(vertexItem2);

            scene->addItem(vertexItem2);
            polygon << QPointF(x2, y1);
            polygonItem->setRectangle();


            polygonItem->setPolygon(polygon);
            recoverData(polygonItem);
            connect(polygonItem, &PolygonItem::requestDelete, this, &MainWindow::onItemRequestDelete);
            connect(polygonItem, &PolygonItem::requestModify, this, &MainWindow::onItemRequestModify);
            scene->addItem(polygonItem);

        }

        if(shapeType == "polygon")
        {
            QPolygonF polygon;
            PolygonItem* polygonItem = new PolygonItem(scene);
            QJsonArray pointsArray = shapeObj.value("points").toArray();
            int i = 0;
            for (const QJsonValue &pointVal : pointsArray) {
                QJsonArray point = pointVal.toArray();
                if (point.size() != 2)
                    continue;

                qreal x = point[0].toDouble();
                qreal y = point[1].toDouble();
                polygon << QPointF(x, y);
                VertexItem* vertexItem = new VertexItem(QPointF(x, y), VertexItem::Placed, scene);
                vertexItem->setIndex(i++);
                vertexItem->setPolygonItem(polygonItem);
                polygonItem->myVertexes.append(vertexItem);
                polygonItem->setText(label);
                scene->addItem(vertexItem);
            }
            polygonItem->setPolygon(polygon);
            recoverData(polygonItem);
            connect(polygonItem, &PolygonItem::requestDelete, this, &MainWindow::onItemRequestDelete);
            connect(polygonItem, &PolygonItem::requestModify, this, &MainWindow::onItemRequestModify);
            scene->addItem(polygonItem);
        }


        // Debug: print polygon
        // qDebug() << "Polygon loaded with" << polygon.size() << "points:" << polygon;

        // 👉 TODO: 后续将其显示到 scene 中


    }

}

void MainWindow::recoverData(PolygonItem *item)
{
    QStringList list = labelNameListModel->labelNames();
    QString text = item->text();
        // 继续使用 text 设置 item 的标签

    if (text != "") {
        model->addItem(item, text);
    }
}
